package com.ec50n9.server.controllerAdvice

import com.ec50n9.server.common.ApiException
import com.ec50n9.server.common.NotControllerResponseAdvice
import com.ec50n9.server.module.common.AjaxResult
import com.ec50n9.server.module.common.BaseCode
import com.fasterxml.jackson.core.JsonProcessingException
import com.fasterxml.jackson.databind.ObjectMapper
import org.springdoc.webmvc.api.OpenApiWebMvcResource
import org.springframework.core.MethodParameter
import org.springframework.http.MediaType
import org.springframework.http.converter.HttpMessageConverter
import org.springframework.http.server.ServerHttpRequest
import org.springframework.http.server.ServerHttpResponse
import org.springframework.web.bind.annotation.RestControllerAdvice
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice

/**
 * 返回结果封装
 */
@RestControllerAdvice
class ResponseAdvice : ResponseBodyAdvice<Any> {

    override fun supports(returnType: MethodParameter, converterType: Class<out HttpMessageConverter<*>>) =
        // 已封装
        !returnType.parameterType.isAssignableFrom(AjaxResult::class.java)
                // 已加注解
                && !returnType.hasMethodAnnotation(NotControllerResponseAdvice::class.java)
                // api-doc文档
                && returnType.method?.declaringClass != OpenApiWebMvcResource::class.java

    override fun beforeBodyWrite(
        body: Any?,
        returnType: MethodParameter,
        selectedContentType: MediaType,
        selectedConverterType: Class<out HttpMessageConverter<*>>,
        request: ServerHttpRequest,
        response: ServerHttpResponse
    ): Any? {
        val ajaxResult = AjaxResult.success(body)
        if (returnType.genericParameterType == String::class.java) {
            try {
                return ObjectMapper().writeValueAsString(ajaxResult)
            } catch (e: JsonProcessingException) {
                throw ApiException(BaseCode.RESPONSE_PACK_ERROR, e.message)
            }
        }
        return ajaxResult
    }
}
